<template>
  <div class="pageContainer">
    <div class="leftContainer">
      <!--  左侧Dnd  -->
      <div v-if="props.mode === 'edit'" class="dndContainer">
        <div class="leftTop">
          <el-input
            v-model="searchStatus"
            style="width: 100%"
            placeholder="搜索状态名称"
            :prefix-icon="Search"
            @change="handleSearchStatus"
          />
          <el-button @click="handleAddStatus" type="primary">
            <img src="@/assets/lifecycle/addBlue.svg" />
          </el-button>
        </div>

        <ul id="Dnd" class="statusList">
          <li
            :style="{
              backgroundColor: hexToRgba(item.color, 0.1),
              color: item.color,
            }"
            v-for="(item, index) in statusList"
            :key="index"
            class="statusItem"
            data-type="lifecycle-base-node"
            @mousedown="startDrag(item, $event)"
          >
            <!--          <el-icon :color="item.color">-->
            <!--            <CircleCheck />-->
            <!--          </el-icon>-->
            {{ item.name?.zh_CN || "" }}
            <!--          <span class="statusName"></span>-->
          </li>
          <!--          生命周期自定义-->
          <li
            :style="{
              backgroundColor: hexToRgba(item.color, 0.1),
              color: item.color,
            }"
            v-for="(item, index) in customStatusList"
            :key="index"
            class="statusItem"
            data-type="lifecycle-base-node"
            @mousedown="startDrag(item, $event)"
          >
            <!--          <el-icon :color="item.color">-->
            <!--            <CircleCheck />-->
            <!--          </el-icon>-->
            {{ item.name?.zh_CN || "" }}
            <!--          <span class="statusName"></span>-->
          </li>
        </ul>
      </div>
      <!--      状态成熟度-->
      <div class="statusMaturity">
        <div class="title">状态成熟度</div>
        <div
          style="
            font-size: 14px;
            color: #5e5e5e;
            text-align: right;
            position: absolute;
            right: 18px;
            top: 46px;
          "
        >
          状态类型
        </div>
        <div v-for="item in nodeList" :key="item.id" class="statusMaturityItem">
          <div class="top">
            <span>{{ item.name?.zh_CN || "" }}</span>
          </div>
          <div class="bottom">
            <el-slider
              v-model="item.progress"
              show-input
              :show-input-controls="false"
              input-size="small"
              :disabled="props.mode === 'preview'"
              @change="handleChangeSlider(item)"
            />
            <el-select
              v-model="item.code"
              size="small"
              style="width: 80px"
              :disabled="props.mode === 'preview'"
              @change="handleChangeSlider(item)"
            >
              <el-option
                style="
                  width: 60px;
                  padding-left: 5px;
                  padding-right: 5px;
                  font-size: 12px;
                  text-align: center;
                "
                v-for="item in statusOptions"
                :key="item.code"
                :value="item.code"
                :label="item.displayName"
              ></el-option>
            </el-select>
          </div>
        </div>
      </div>
    </div>

    <div class="lifecycleCanvasContainer">
      <div class="graph" id="graph-container"></div>
      <!--   zoom   -->
      <div class="zoomController">
        <span @click="handleZoom('odd')" class="icon">
          <img
            style="width: 100%; height: 100%"
            src="@/assets/lifecycle/zoomOdd.svg"
          />
        </span>
        <span class="text">{{ currentZoom }}%</span>
        <span @click="handleZoom('add')" class="icon">
          <img
            style="width: 100%; height: 100%"
            src="@/assets/lifecycle/zoomOdd.svg"
          />
        </span>
      </div>
      <TeleportContainer />
    </div>
    <CDialog
      :title="'迁移（工作项状态流转设置）'"
      v-model="dialogEditEdgeVisible"
      @handleDialogOk="handleEditLifecycleNode"
      :fields="dialogEditEdgeFields"
      :nodeData="lifecycleEdgeDialogData"
    >
      <template #bottomSlot>
        <settingEdgeCondition />
      </template>
    </CDialog>
    <!--    新建自定义状态-->
    <CDialog
      :title="'新增生命周期状态'"
      v-model="addDialogVisible"
      @handleDialogOk="handleCreateCustomStatus"
      :fields="statusDialogFields"
      :nodeData="{}"
    ></CDialog>
    <teleport to="body">
      <div
        :style="{
          top: popoverPosition.y + 'px',
          left: popoverPosition.x + 'px',
        }"
        v-show="isShowPopover"
        class="edgePopoverClass"
      >
        <ul class="popoverList">
          <li @click="handleSetting" class="popoverItem">
            <img src="@/assets/lifecycle/setting.svg" />迁移(状态流转)
          </li>
          <li style="color: #d54941" @click="handleDelEdge" class="popoverItem">
            <img src="@/assets/lifecycle/delete.svg" />删除连线
          </li>
        </ul>
      </div>
    </teleport>
  </div>
</template>
<script setup lang="ts">
  import { deepCopy, hexToRgba } from "@/utils/common.ts";
  import "./components/registerTools.ts";
  import "./components/registerNode.js";
  import EdgeBtn from "./components/edgeBtn.vue";
  import settingEdgeCondition from "./components/settingEdgeCondition.vue";
  import {
    ref,
    onMounted,
    render,
    h,
    onBeforeUnmount,
    provide,
    watch,
  } from "vue";
  import { useRoute } from "vue-router";
  import { Search } from "@element-plus/icons-vue";
  import { Cell, Graph, Shape, Markup, Edge } from "@antv/x6";
  import { Transform } from "@antv/x6-plugin-transform";
  import { Selection } from "@antv/x6-plugin-selection";
  import { Snapline } from "@antv/x6-plugin-snapline";
  import { Keyboard } from "@antv/x6-plugin-keyboard";
  import { Clipboard } from "@antv/x6-plugin-clipboard";
  import { History } from "@antv/x6-plugin-history";
  import { Dnd } from "@antv/x6-plugin-dnd";
  import { getTeleport } from "@antv/x6-vue-shape";
  import {
    getLifeCycle,
    updateLifeCycle,
    listLifeGlobalStatus,
    saveLifeCycleEdge,
    saveLifeCycleNode,
    deleteLifeCycleNode,
    deleteLifeCycleEdge,
    getLifecycleFieldList,
  } from "@/api/lifeCycle.ts";
  import {
    type createLifeCycleParams,
    type lifecycleEdge,
    type LifeCycleEntity,
    type lifecycleNode,
    type LifeGlobalStatus,
    type queryPagesType,
    type saveLifecycleEdgeParams,
    type saveLifecycleNodeParams,
    type Value,
  } from "@/interface/lifecycle.ts";
  import type { lifecycleBaseNodeDataType } from "./interface";
  import CDialog from "@/components/CDialog.vue";
  import {
    type DynamicField,
    mockCreateFieldsLifecycleStatus,
    mockLifecycleEdgeFields,
  } from "@/data/wbsFields.ts";
  import { ElMessage } from "element-plus";

  interface propsType {
    lifecycleId: string;
    mode: string;
  }
  const props = defineProps<propsType>();
  provide("mode", props.mode);

  watch(
    () => props.lifecycleId,
    async () => {
      // console.log("watch", props.lifecycleId);
      if (props.lifecycleId) {
        await getLifecycleDetails();
        renderGraph();
      } else {
        lifecycleDetails.value = {} as LifeCycleEntity;
        nodeList.value = [];
        customStatusList.value = [];
        renderGraph();
      }
    },
  );
  const TeleportContainer = getTeleport();
  const route = useRoute();

  const currentZoom = ref(1);
  const isShowPopover = ref(false);
  const popoverPosition = ref<{ x: number; y: number }>({ x: 0, y: 0 });
  const dialogEditEdgeVisible = ref(false);
  const dialogEditEdgeFields = ref<DynamicField[]>(mockLifecycleEdgeFields);
  const lifecycleEdgeDialogData = ref<lifecycleEdge>({});
  let currentEditEdge: Edge<Edge.Properties> | null;

  let timer: any;
  // Dnd
  let dnd: Dnd | null = null;
  const statusList = ref<LifeGlobalStatus[]>([]);
  const customStatusList = ref<LifeGlobalStatus[]>([]);
  const searchStatus = ref("");
  const initDnd = () => {
    dnd = new Dnd({
      target: graph!,
      scaled: false,
      dndContainer: document.getElementById("Dnd")!,
      getDropNode(node) {
        const nodeData = node.getData();
        // 返回一个新的节点作为实际放置到画布上的节点
        const newNode = graph!.createNode({
          shape: "lifecycle-base-node",
          label: "步骤",
          data: {
            ...nodeData,
          },
        });
        return newNode;
      },
    });
  };
  const handleAddStatus = () => {
    addDialogVisible.value = true;
  };
  const startDrag = (item: LifeGlobalStatus, e: MouseEvent) => {
    const target = e.currentTarget as HTMLElement;
    console.log("startDrag", item);
    const type = target.getAttribute("data-type");
    let node;
    if (type === "lifecycle-base-node") {
      node = graph!.createNode({
        shape: "lifecycle-base-node",
        label: "步骤",
        data: {
          statusInfo: item,
          lifecycleInfo: {
            id: lifecycleDetails.value.id,
            type: lifecycleDetails.value.type,
            name: lifecycleDetails.value.name,
            remark: lifecycleDetails.value.remark,
            model: lifecycleDetails.value.model,
            status: lifecycleDetails.value.status,
            statusCard: lifecycleDetails.value.statusCard,
          },
          nodeInfo: {
            name: item.name?.zh_CN,
            color: item.color,
          },
        },
      });
    }
    if (node) dnd!.start(node, e);
  };

  // Graph
  let graph: Graph | null = null;
  const initGraph = () => {
    graph = new Graph({
      container: document.getElementById("graph-container")!,
      onEdgeLabelRendered: (args) => {
        // const edgeData = args.edge.getData<lifecycleEdge>();
        console.log("onEdgeLabelRendered", args);
        const { selectors } = args;
        const content = selectors.foContent as HTMLDivElement;
        if (content) {
          content.style.display = "flex";
          content.style.justifyContent = "center";
          content.style.alignItems = "center";
          render(
            h(EdgeBtn, {
              mode: props.mode,
              nodeList: nodeList,
              edge: args.edge,
              onClickShow: (edge, pos) => {
                currentEditEdge = edge;
                isShowPopover.value = true;
                popoverPosition.value.x = pos.x;
                popoverPosition.value.y = pos.y;
              },
            }),
            content,
          );
        }
        return undefined;
      },
      grid: {
        size: 10,
        visible: true,
        args: {
          color: "#a0a0a0", // 网点颜色
          thickness: 1, // 网点大小
        },
      },
      background: {
        color: "#f8f9fc",
      },
      panning: true, // 可移动
      autoResize: true,
      interacting:
        props.mode === "preview"
          ? false
          : {
              edgeLabelMovable: false,
            },
      mousewheel: {
        enabled: true,
        zoomAtMousePosition: true,
        modifiers: "ctrl",
        minScale: 0.1,
        maxScale: 3,
      },
      connecting: {
        router: "manhattan",
        connector: {
          name: "rounded",
          args: {
            radius: 8,
          },
        },
        anchor: "center",
        connectionPoint: "anchor",
        allowBlank: false,
        allowLoop: false,
        allowNode: true,
        snap: {
          radius: 20,
        },
        createEdge() {
          // console.log('createEdge', e)
          return new Shape.Edge({
            attrs: {
              line: {
                stroke: "#A2B1C3",
                strokeWidth: 2,
                targetMarker: {
                  name: "block",
                  width: 12,
                  height: 8,
                },
              },
            },
            defaultLabel: {
              markup: Markup.getForeignObjectMarkup(),
              attrs: {
                fo: {
                  width: 72,
                  height: 28,
                  x: -36,
                  y: -14,
                },
              },
            },
            label: {
              position: 0.5,
            },
            zIndex: 0,
          });
        },
        validateConnection({ targetMagnet }) {
          return !!targetMagnet;
        },
      },
      // highlighting: {
      //   magnetAdsorbed: {
      //     name: "stroke",
      //     args: {
      //       attrs: {
      //         fill: "#5F95FF",
      //         stroke: "#5F95FF",
      //       },
      //     },
      //   },
      // },
      // translating: { restrict: true },
    });
    // #region 使用插件
    graph
      .use(
        new Transform({
          // resizing: false,
          resizing: false,
          rotating: false,
        }),
      )
      .use(
        new Selection({
          enabled: false,
          rubberband: true,
          showNodeSelectionBox: true,
        }),
      )
      .use(new Snapline())
      .use(new Keyboard())
      .use(new Clipboard())
      .use(new History());
    // 控制连接桩显示/隐藏
    const showPorts = (ports: NodeListOf<Element>, show: boolean) => {
      if (props.mode === "preview") return;
      for (let i = 0, len = ports.length; i < len; i += 1) {
        ports[i].style.visibility = show ? "visible" : "hidden";
      }
    };
    graph.bindKey("delete", () => {
      if (!graph) return;
      if (props.mode === "preview") return;
      const cells = graph.getSelectedCells();
      // console.log("cells", cells);
      if (cells.length === 0) return;
      graph.removeCells(cells);
    });
    // 移动节点
    graph.on("node:moved", ({ node }) => {
      // console.log('node:moved', node, x, y)
      updateListLifeCycleLayout("update", "node", node, true);
    });
    graph.on("node:added", ({ node }) => {
      // 添加节点
      // console.log("node", node);
      updateListLifeCycleLayout("create", "node", node, false);
    });
    graph.on("edge:connected", ({ edge, isNew }) => {
      if (isNew) {
        updateListLifeCycleLayout("create", "edge", edge, false);
      }
    });
    graph.on("cell:removed", ({ cell }) => {
      console.log("cell", cell);
      updateListLifeCycleLayout(
        "delete",
        cell.shape === "edge" ? "edge" : "node",
        cell,
        false,
      );
    });
    graph.on("cell:click", ({ cell }) => {
      // console.log("cell", cell);
      graph?.resetSelection([cell]);
    });
    graph.on("edge:mouseenter", ({ edge }) => {
      edge.setData({ showAdd: true });
      // edge.addTools({
      //   name: "lifecycleEdgeTool",
      //   args: {
      //     tooltip: "Tooltip Content",
      //   },
      // });
    });
    graph.on("edge:mouseleave", ({ edge }) => {
      edge.setData({ showAdd: false });
      // edge.removeTool("lifecycleEdgeTool");
    });
    graph.on("blank:mousemove", () => {
      // console.log("blank");
      // currentZoom.value = Math.ceil(graph?.zoom()! * 100);
      // edge.removeTool("lifecycleEdgeTool");
    });
    graph.on("edge:selected", ({ edge }) => {
      edge.attr("line/stroke", "#2BA471");
      edge.attr("line/strokeWidth", 3);
      edge.setZIndex(1); // 提高层级
    });
    graph.on("edge:unselected", ({ edge }) => {
      edge.attr("line/stroke", "#A2B1C3");
      edge.attr("line/strokeWidth", 2);
      edge.setZIndex(0); // 恢复层级
    });
    graph.on("node:mouseenter", () => {
      const container = document.getElementById("graph-container")!;
      const ports = container.querySelectorAll(".x6-port-body");
      showPorts(ports, true);
    });
    graph.on("node:mouseleave", () => {
      const container = document.getElementById("graph-container")!;
      const ports = container.querySelectorAll(".x6-port-body");
      showPorts(ports, false);
    });
  };

  // 自适应缩放函数
  const fitGraphContent = (padding = 50, maxZoom = 1, minZoom = 0.6) => {
    // 获取所有单元格的边界
    const cells = graph!.getCells();
    if (cells.length === 0) return;

    // 计算内容边界
    let minX = Infinity;
    let minY = Infinity;
    let maxX = -Infinity;
    let maxY = -Infinity;

    cells.forEach((cell) => {
      const bbox = cell.getBBox();
      minX = Math.min(minX, bbox.x);
      minY = Math.min(minY, bbox.y);
      maxX = Math.max(maxX, bbox.x + bbox.width);
      maxY = Math.max(maxY, bbox.y + bbox.height);
    });

    // 计算需要的缩放比例
    const graphWidth = graph!.container.clientWidth;
    const graphHeight = graph!.container.clientHeight;

    const contentWidth = maxX - minX + padding * 2;
    const contentHeight = maxY - minY + padding * 2;

    const scaleX = graphWidth / contentWidth;
    const scaleY = graphHeight / contentHeight;

    // 选择较小的缩放比例以确保内容完全可见
    let zoom = Math.min(scaleX, scaleY);

    // 限制缩放范围
    zoom = Math.min(maxZoom, Math.max(minZoom, zoom));

    // 计算中心点
    const centerX = (minX + maxX) / 2;
    const centerY = (minY + maxY) / 2;
    // console.log(zoom, centerX, centerY, "centerX");
    // 应用缩放和平移
    graph!.zoomTo(zoom, {
      // absolute: true,
      center: {
        x: centerX,
        y: centerY,
      },
    });

    // 将内容居中
    graph!.centerContent();
  };

  let lifecycleDetails = ref<LifeCycleEntity>({} as LifeCycleEntity);
  const renderGraph = () => {
    if (lifecycleDetails.value.layout) {
      graph?.fromJSON(JSON.parse(lifecycleDetails.value.layout));
    } else {
      graph?.fromJSON({ cells: [], edges: [] });
    }
    fitGraphContent();
    currentZoom.value = Math.ceil(graph?.zoom()! * 100);
  };

  const handleSearchStatus = () => {
    console.log("handleSearchStatus", searchStatus.value);
    // statusList.value = statusList.value.filter((item) =>
    //   item.name?.zh_CN.includes(searchStatus.value),
    // );
    // customStatusList.value = statusList.value.filter((item) =>
    //   item.name?.zh_CN.includes(searchStatus.value),
    // );
  };

  const handleSetting = () => {
    const edgeData = currentEditEdge!.getData();
    console.log("handleSetting", edgeData);
    dialogEditEdgeVisible.value = true;
    lifecycleEdgeDialogData.value = deepCopy(edgeData);
    lifecycleEdgeDialogData.value.buttonName = edgeData.buttonName?.zh_CN;
    isShowPopover.value = false;
  };
  const handleDelEdge = () => {
    graph?.removeEdge(currentEditEdge!);
    isShowPopover.value = false;
  };

  const handleEditLifecycleNode = async (formData: lifecycleEdge) => {
    // console.log("handleEditLifecycleNode", formData);
    const params: saveLifecycleEdgeParams = {
      id: lifecycleDetails.value.id,
      edge: {
        id: formData.id,
        fromNodeId: formData.fromNodeId,
        toNodeId: formData.toNodeId,
        name: formData.name,
        buttonName: {
          zh_CN: formData.buttonName,
        },
        remark: formData.remark,
        tag: formData.tag,
        auditId: formData.auditId,
        transferRules: formData.transferRules,
        permissionRule: formData.permissionRule,
      },
    };
    console.log("params", params);
    // return;
    updateListLifeCycleLayout(
      "update",
      "edge",
      currentEditEdge!,
      false,
      params,
    );
  };

  // 保存画布布局
  const updateListLifeCycleLayout = async (
    operate: string,
    type: string,
    cell: Cell<Cell.Properties>,
    onlySaveCanvas: boolean = false,
    updateParams?: saveLifecycleEdgeParams | saveLifecycleNodeParams,
  ) => {
    console.log("updateListLifeCycleLayout", operate, cell);
    if (onlySaveCanvas) {
      const params: createLifeCycleParams = {
        id: props.lifecycleId,
        layout: JSON.stringify(graph?.toJSON()),
        name: lifecycleDetails.value.name,
        remark: lifecycleDetails.value.remark,
        status: lifecycleDetails.value.status,
        statusCard: lifecycleDetails.value.statusCard,
        // model: lifecycleDetails.value.model,
        type: lifecycleDetails.value.type,
      };
      await updateLifeCycle(params);
      return;
    }
    // return;
    if (operate === "create") {
      if (type === "node") {
        const nodeData = cell.getData() as lifecycleBaseNodeDataType;
        const params: saveLifecycleNodeParams = {
          id: props.lifecycleId,
          node: {
            name: nodeData.statusInfo.name,
            code: nodeData.statusInfo.code?.code,
            progress: 0,
            isAuditing: false,
            color: nodeData.statusInfo.color,
          },
        };
        const res = await saveLifeCycleNode(params);
        cell.setData({
          nodeInfo: res,
        });
        console.log("cell", cell);
      } else if (type === "edge") {
        const fromNode = graph?.getCellById(cell.source.cell);
        const toNode = graph?.getCellById(cell.target.cell);
        if (fromNode && toNode) {
          const fromNodeData = fromNode.getData<lifecycleBaseNodeDataType>();
          const toNodeData = toNode.getData<lifecycleBaseNodeDataType>();
          const params: saveLifecycleEdgeParams = {
            id: props.lifecycleId,
            edge: {
              fromNodeId: fromNodeData.nodeInfo.id,
              toNodeId: toNodeData.nodeInfo.id,
              name: {
                zh_CN: "",
                en_US: "",
              },
              buttonName: {
                zh_CN: "",
                en_US: "",
              },
              remark: "",
              tag: "",
              auditId: "",
              transferRules: [],
              permissionRule: {},
            },
          };
          const res = await saveLifeCycleEdge(params);
          cell.setData(res);
          console.log("createEdge", res);
        }
        // const fromNodeData = c
        // return;
      }
    } else if (operate === "delete") {
      if (type === "node") {
        // const nodeData
        const nodeData = cell.getData<lifecycleBaseNodeDataType>();
        // console.log(cell.getData());
        await deleteLifeCycleNode(props.lifecycleId, nodeData.nodeInfo.id!);
      } else if (type === "edge") {
        if (!cell.target.cell) return;
        const edgeData = cell.getData<lifecycleEdge>();
        await deleteLifeCycleEdge(props.lifecycleId, edgeData.id!);
        currentEditEdge = null;
      }
    } else if (operate === "update") {
      if (type === "node") {
      } else if (type === "edge") {
        const data = await saveLifeCycleEdge(
          updateParams as saveLifecycleEdgeParams,
        );
        dialogEditEdgeVisible.value = false;
        cell.setData(data);
        currentEditEdge = null;
      }
    }
    // return;
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(async () => {
      const params: createLifeCycleParams = {
        id: props.lifecycleId,
        layout: JSON.stringify(graph?.toJSON()),
        name: lifecycleDetails.value.name,
        remark: lifecycleDetails.value.remark,
        status: lifecycleDetails.value.status,
        statusCard: lifecycleDetails.value.statusCard,
        // model: lifecycleDetails.value.model,
        type: lifecycleDetails.value.type,
      };
      await updateLifeCycle(params);
      getLifecycleDetails();
      timer = null;
    }, 150);
  };

  const getLifecycleDetails = async () => {
    // console.log("getLifecycleDetails", route.query);
    const res = await getLifeCycle(props.lifecycleId);
    lifecycleDetails.value = res;
    nodeList.value = res.model?.nodes || [];
    customStatusList.value = JSON.parse(
      lifecycleDetails.value.statusCard,
    ) as LifeGlobalStatus[];
    // console.log(
    //   JSON.parse(lifecycleDetails.value.statusCard),
    //   "lifecycleDetail",
    // );
  };

  const getGlobalStatus = async () => {
    const params: queryPagesType = {
      pageNo: 1,
      pageSize: 999,
      conditions: [],
    };
    const res = await listLifeGlobalStatus(params);
    statusList.value = res.result || [];
  };
  const clickBody = () => {
    isShowPopover.value = false;
    // currentEditEdge = null;
  };
  const handleZoom = (type: string) => {
    if (type === "add") {
      graph?.zoomTo(graph?.zoom() + 0.1);
    } else {
      graph?.zoomTo(graph?.zoom() - 0.1);
    }
    currentZoom.value = Math.ceil(graph?.zoom()! * 100);
  };

  // 状态成熟度
  const nodeList = ref<lifecycleNode[]>([]);
  const statusOptions = ref<Value[]>([]);

  const getStatusOptions = async () => {
    const res = await getLifecycleFieldList();
    // console.log(res.find((item) => item.code === "status"));
    statusOptions.value =
      res.find((item) => item.code === "STATUS")?.values || [];
    console.log(statusOptions.value, "statusOptions.value");
  };

  const handleChangeSlider = async (item: lifecycleNode) => {
    console.log("handleChangeSlider", item);
    await saveLifeCycleNode({
      id: props.lifecycleId,
      node: item,
    });
  };

  // 自定义状态
  const addDialogVisible = ref(false);
  const statusDialogFields = ref<DynamicField[]>([]);
  const getStatusFields = () => {
    statusDialogFields.value = mockCreateFieldsLifecycleStatus.map((item) => {
      if (item.field === "code") {
        item.options = statusOptions.value.map((item) => {
          return {
            label: item.displayName,
            value: item.code,
          };
        });
      }
      return item;
    });
  };
  const handleCreateCustomStatus = async (formData: any) => {
    console.log("formData", formData);
    const item: LifeGlobalStatus = {
      color: formData.color,
      name: {
        zh_CN: formData.name,
      },
      id: new Date().getTime() + "",
      code: {
        code: formData.code,
        name: {
          zh_CN: statusOptions.value.find((item) => item.code === formData.code)
            ?.displayName,
        },
      },
    };
    const statusCard = JSON.parse(lifecycleDetails.value.statusCard || "[]");
    statusCard.push(item);
    const params: createLifeCycleParams = {
      id: props.lifecycleId,
      // layout: JSON.stringify(graph?.toJSON()),
      name: lifecycleDetails.value.name,
      remark: lifecycleDetails.value.remark,
      status: lifecycleDetails.value.status,
      statusCard: JSON.stringify(statusCard),
      // model: lifecycleDetails.value.model,
      type: lifecycleDetails.value.type,
    };
    await updateLifeCycle(params);
    ElMessage({
      type: "success",
      message: "添加成功",
    });
    getLifecycleDetails();
    addDialogVisible.value = false;
    console.log(item, lifecycleDetails.value.statusCard, statusCard);
  };

  provide("updateLifecycleData", () => {
    getLifecycleDetails();
  });
  onMounted(async () => {
    initGraph();
    initDnd();
    getGlobalStatus();
    await getStatusOptions();
    getStatusFields();
    if (props.lifecycleId) {
      await getLifecycleDetails();

      renderGraph();
    }

    setTimeout(() => {
      graph && graph.centerPoint(0, 0);
    }, 100);
    document.body.addEventListener("click", clickBody);
  });
  onBeforeUnmount(() => {
    document.body.removeEventListener("click", clickBody);
  });
</script>

<style scoped lang="scss">
  .pageContainer {
    width: 100%;
    height: 99.9%; // 解决100%是有时候会溢出一点高度导致出现滚动条
    position: relative;
    .leftContainer {
      position: absolute;
      top: 15px;
      left: 15px;
      z-index: 1;
      .dndContainer {
        //position: absolute;
        box-sizing: border-box;
        //left: 15px;
        //top: 15px;
        width: 352px;
        //height: calc(100% - 30px);
        //padding: 12px;
        overflow: auto;
        //background: #fff;
        //z-index: 1;
        margin-bottom: 15px;
        display: flex;
        flex-direction: column;
        justify-content: space-between;
        .el-button--primary {
          padding-left: 0;
          padding-right: 0;
        }
        background: #fff;
        padding: 12px;
        box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.1);
        border-radius: 4px;
        .leftTop {
          display: flex;
          height: 32px;
          justify-content: space-between;
          align-items: center;
          margin-bottom: 10px;
          gap: 8px;
          input::placeholder {
            font-size: 12px !important;
            color: #999 !important;
          }
          span {
            font-size: 14px;
            font-weight: bold;
            color: #303033;
          }
        }
        .statusList {
          user-select: none;
          list-style: none;
          padding: 0;
          margin: 15px 0 0 0;
          display: flex;
          flex-wrap: wrap;
          gap: 8px;
          max-height: 50%;
          align-content: flex-start;
          .statusItem {
            width: 104px;
            box-sizing: border-box;
            height: 32px;
            border-radius: 4px;
            display: flex;
            align-items: center;
            padding: 0 5px;
            //border: 1px solid #0ab169;
            font-size: 13px;
            line-height: 17px;
            font-weight: 500;
            color: #2e405e;
            cursor: pointer;
            justify-content: center;
            //box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.15);

            .statusName {
              margin-left: 5px;
            }
          }
        }
      }
      .statusMaturity {
        overflow: auto;
        box-sizing: border-box;
        position: relative;
        background: #fff;
        height: 355px;
        //left: 15px;
        //bottom: 15px;
        //z-index: 1;
        width: 352px;
        box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.1);
        border-radius: 4px;
        padding: 0 12px;
        -ms-overflow-style: none; /* IE and Edge */
        scrollbar-width: none; /* Firefox */
        ::-webkit-scrollbar {
          display: none;
        }
        .title {
          font-size: 14px;
          color: #141414;
          line-height: 22px;
          font-weight: 500;
          padding: 12px 0;
          position: sticky;
          top: 0;
          left: 0;
          background: #fff;
          z-index: 999;
        }
        .statusMaturityItem {
          margin-bottom: 10px;
          .top {
            display: flex;
            align-items: center;
            justify-content: space-between;
            height: 22px;
            margin-bottom: 3px;

            span {
              font-size: 14px;
              color: #141414;
            }
          }
          .bottom {
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: 8px;
            :deep(.el-select__wrapper) {
              box-shadow: none !important;
              padding: 2px !important;
            }
            :deep(.el-slider__input) {
              width: 48px;
            }
            :deep(.el-input-number.is-without-controls .el-input__wrapper) {
              padding-left: 13px;
              padding-right: 13px;
            }
            :deep(.el-slider__runway.show-input) {
              margin-left: 12px;
              margin-right: 12px;
            }
          }
        }
      }
    }

    .lifecycleCanvasContainer {
      width: 100%;
      height: 100%;
      overflow: hidden;
      position: relative;
      .zoomController {
        box-sizing: border-box;
        position: absolute;
        bottom: 76px;
        right: 40px;
        width: 155px;
        height: 48px;
        border-radius: 4px;
        background: #ffffff;
        box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.06);
        padding: 4px 8px;
        display: flex;
        justify-content: space-between;
        .text {
          flex: 1;
          height: 40px;
          line-height: 40px;
          text-align: center;
          color: #5e5e5e;
          font-size: 15px;
        }
        .icon {
          width: 40px;
          height: 40px;
          border-radius: 4px;
          background: #ffffff;
          cursor: pointer;
          &:hover {
            background: #f2f2f2;
          }
        }
      }
    }
  }
</style>
<style lang="scss" scoped>
  :deep(.x6-widget-selection-box) {
    display: none;
  }
  .edgePopoverClass {
    position: absolute;
    width: 141px;
    top: 27px;
    border: 1px solid #f2f2f2;
    padding: 4px;
    border-radius: 4px;
    box-shadow: 0 1px 8px 0 rgba(0, 0, 0, 0.16);
    background: #fff;
    .popoverList {
      padding: 0;
      margin: 0;
      list-style: none;
      .popoverItem {
        font-size: 14px;
        color: #2e405e;
        height: 32px;
        border-radius: 4px;
        background: #fff;
        transition: background-color 0.2s;
        cursor: pointer;
        display: flex;
        align-items: center;
        padding: 0 9px;
        &:hover {
          background: #f5f6f8;
        }
        img {
          width: 14px;
          height: 14px;
          margin-right: 9px;
        }
      }
    }
  }
</style>
